from celery import shared_task
from api import models
from django.db import transaction
import datetime
import uuid
import itertools

@shared_task
def end_auction_task(auction_id):
    '''
    结束拍卖后执行的定时任务
    :param auction_id:
    :return:
    '''
    #状态更新
    models.Auction.objects.filter(pk=auction_id).update(status=4)  #修改拍卖场次的状态
    models.AuctionItem.objects.filter(auction_id=auction_id).update(status=4) #修改该排场 中拍品的状态
    #
    auction=models.Auction.objects.filter(pk=auction_id).first()  #获取该排场
    auction_item_set=models.AuctionItem.objects.filter(auction_id=auction_id) #获取该排场中所有的拍品
    total=0 #总成交价 该拍卖场
    luck_auction_deposit_id=set()  #所有已经拍到商品的人 缴纳的保证金是全场保证金记录集合
    total_unfortunate_list=[] #所有没有拍卖到的 保证金记录
    #循环拍卖场中的拍品
    for item in auction_item_set:
        #竞价记录 把出价最高者的状态变更为成交
        luck_obj=models.BidRecord.objects.filter(item=item).order_by('-price').first()
        item_unfortunate_list=None  #没有拍的该商品  缴纳单品保证金的 保证金记录列表
        if not luck_obj:
            #没有人出价   拍品设置为流拍
            item.status=5
            item.save()
            item_unfortunate_list = models.DepositRecord.objects.filter(item=item,
                                                                        deposit_type=1,
                                                                        auction=auction,
                                                                        status=2)
            total_unfortunate_list.extend(item_unfortunate_list)
            continue
        else:
            with transaction.atomic():
                luck_obj.status = 2
                luck_obj.save()
                # 拍品设置成交价
                item.deal_price = luck_obj.price
                item.save()
                #加入总成交价中
                total += luck_obj.price
                #获取出价最高值的单场 单品保证金的记录表
                deposit_obj=models.DepositRecord.objects.filter(user=luck_obj.user,
                                                                item=item,
                                                                deposit_type=1,
                                                                auction=auction,
                                                                status=2
                                                                ).first()
                #全场保证金
                if not deposit_obj:
                    deposit_obj=models.DepositRecord.objects.filter(user=luck_obj.user,
                                                                    deposit_type=2,
                                                                    auction = auction,
                                                                    status = 2,
                                                                    item__isnull = True
                                                                    )
                    luck_auction_deposit_id.add(deposit_obj.pk) #已经拍的商品 并且缴纳 全场保证金的  记录集合
                #为当前用户创建订单  待支付
                order=models.Order.objects.create(user=luck_obj.user,
                                                  uid=str(uuid.uuid4()),
                                                  item=item,
                                                  deposit=deposit_obj,
                                                  price=luck_obj.price
                                                  )
                # 获取utc时间的24小时后的时间
                date = datetime.utcnow() + datetime.timedelta(hours=24)
                #调度24小时内没有付款的定时任务 ，没有付款 扣除保证金
                task_id = twenty_four_hour.apply_async(args=[order],eta=date).id
                order.twenty_four_task_id=task_id
                order.save()
                #未拍卖到该商品的用户的保证金记录
                item_unfortunate_list=models.DepositRecord.objects.filter(item=item,
                                                                          deposit_type=1,
                                                                          auction=auction,
                                                                          status=2).exclude(user = luck_obj.user)
                #需要退还保证金的 保证金记录列表
                total_unfortunate_list.extend(item_unfortunate_list)

    #专场 更新成交价
    auction.total_price=total
    auction.save()
    #未拍的商品的用户 全场保证金
    auction_unfortunate_deposit_record_list=models.DepositRecord.objects.filter(deposit_type=2,
                                                                                auction=auction,
                                                                                status = 2,
                                                                                item__isnull = True,
                                                                                ).exclude(
        id__in = luck_auction_deposit_id)
    #退还保证金
    for deposit_record in itertools.chain(total_unfortunate_list,auction_unfortunate_deposit_record_list):
        uid=str(uuid.uuid4())
        #余额支付
        if deposit_record.pay_type==2:
            with transaction.atomic():
                deposit_record.user.balance+=deposit_record.amount
                deposit_record.user.save()
                models.DepositRefundRecord.objects.create(
                    uid=uid,
                    status=2,
                    amount=deposit_record.amount,
                    deposit=deposit_record
                )
                deposit_record.amount=0
                deposit_record.save()
        #微信支付
        else:
            pass
@shared_task
def twenty_four_hour(order_id):
    '''
    24小时候不支付订单 则直接扣除保证金

    :param order_id:
    :return:
    '''
    order_obj=models.Order.objects.filter(pk=order_id).first()
    try:
        #如果订单没有付款
        if order_obj.status!=1:
            with transaction.atomic():
                #订单改为逾期未付款
                order_obj.status=4
                order_obj.save()
                #拍品状态改为逾期未支付
                order_obj.item.status=6
                order_obj.item.save()
                #单品保证金
                if order_obj.deposit.deposit_type==1:
                    order_obj.deposit.balance=0
                    order_obj.deposit.save()
                    #创建扣除保证金的表记录
                    models.DepositDeduct.objects.create(order=order_obj,amount=order_obj.deposit.amount)
                #全场保证金
                if order_obj.deposit.deposit_type==2:
                    if order_obj.deposit.balance<order_obj.item.deposit:
                        models.DepositDeduct.objects.create(order=order_obj,amount=order_obj.deposit.balance)
                        order_obj.deposit.balance=0
                        order_obj.deposit.save()
                    else:
                        order_obj.deposit.balance-=order_obj.item.deposit
                        order_obj.deposit.save()
                        models.DepositDeduct.objects.create(order=order_obj,amount=order_obj.deposit.amount)
                    #找其他未支付的订单
                    exists=models.Order.objects.filter(status=1,user=order_obj.user,item__auction=order_obj.item__auction).exclude(pk=order_obj.pk).exists()
                    if exists:
                        #处理扣除其他的未支付的保证金
                        return
                    #退还保证金
                    if order_obj.deposit.pay_type==1:#微信支付
                        pass
                    if order_obj.deposit.pay_type == 2:#余额支付
                        pass
    except Exception as e:
        print(e)

